.TITLE MMDRV .IDENT /09.01/ .ENABLE LC ; ; Copyright (c) 1995-1999 by Mentec, Inc., U.S.A. ; All rights reserved ; ; ; This Software is Furnished Under a License And May Be Used ; or Copied Only in Accordance With the Terms of Such License. ; ; ; RSX11M-PLUS RH11/RH70 TM02/TM03 Magnetic Tape Controller Driver ; ; Version 09.01 ; ; ; Modified By: ; ; CS005 -- Handle CALL for Controller Power Fail (C bit set). ; ; ; .PAGE ; Macro Library Calls ; .MCALL ABODF$, HWDDF$, PKTDF$, UCBDF$, UMDIO$, KRBDF$, SCBDF$, QIOSY$ ABODF$ ;Define Abort Codes HWDDF$ ;Define Hardware Registers PKTDF$ ;Define I/O Packet Offsets UCBDF$ ;Define UCB Offsets UMDIO$ ;Define User Mode Diagnostic Definitions KRBDF$ ;Define KRB and KRB1 Offsets SCBDF$ ;Define SCB Offsets QIOSY$ ;Define QIO Functions and Errors ; ; Equated Symbols ; US.ABO=1 ;Abort Request, US.SUP=2 ;Supress Error Recovery, US.PWF=10 ;Power Fail Indication - in U.STS. RETRY=12 ;Retry Count - 10. retries/request. MINREC=14. ;Write Request - Minimum Record Size. REV=2 ;Reverse Bit - Space Operations. NOISE=MINREC ;Anything Smaller than this is Noise .PAGE ; Register Definition and Offsets ; RHCS1 = +0 ;RH Control and Status Register GO= 1 ;Go Bit IE= 100 ;Interrupt Enable RDY= 200 ;RH Controller Ready PSL= 2000 ;Port select DVA= 4000 ;Device Available TRE= 40000 ;Transfer Error CPE= 20000 ;RH Control Bus Parity Error SC= 100000 ;Special Condition ;I/O Commands FC.RWU= 103 ;Rewind Unload/Off-Line FC.RWD= 107 ;Rewind FC.RLS= 113 ;Release Drive FC.ERS= 125 ;Erase 3" Gap FC.WEF= 127 ;Write EOF (tape mark) FC.SPF= 131 ;Space Forward FC.SPR= 133 ;Space Reverse FC.WRT= 161 ;Write FC.RED= 171 ;Read FC.REV= 177 ;Read Reverse FC.CLR= 11 ;Drive Clear RHWC = +2 ;RH Word Count Register RHBA = +4 ;RH Bus Address Register MTFC = +6 ;TM02/TM03 Frame Count Register RHCS2 = +10 ;RH Control and Status Register 2 SCLR= 40 ;RH Controller Clear DPE= 400 ;MASSBUS Data Parity Error MXF= 1000 ;Missed Transfer PGE= 2000 ;Program Error NEM= 4000 ;Non-existent Memory NED= 10000 ;Non-existent Drive UPE= 20000 ;Unibus Parity Error WCE= 40000 ;Write Check Error DLT= 100000 ;Data Late CS2ERR= DLT! WCE! UPE! NED! NEM! PGE! MXF! DPE ;RH TRE Errors MTDS = +12 ;TM02/TM03 Drive Status Register SLA= 1 ;Slave Attention BOT= 2 ;Beginning of Tape TM= 4 ;Tape Mark Detected PES= 40 ;Phase Encoded Status SSC= 100 ;Slave Status Change DRY= 200 ;Drive Ready EOT= 2000 ;End of Tape WRL= 4000 ;Write Lock MOL= 10000 ;Medium On Line PIP= 20000 ;Positioning in Progress ERR= 40000 ;Error - Composite MTER = +14 ;TM02/TM03 Error Register ILF= 1 ;Illegal Function ILR= 2 ;Illegal Register RMR= 4 ;Register Modification Refused CPR= 10 ;Control Bus Parity Error FMT= 20 ;Format Error DPR= 40 ;Data Parity Error INC= 100 ;Incorrectable Data - PE Mode VPE=INC ;Vertical Parity Error - NRZI Mode PEF= 200 ;Format Error - PE Mode LRC=PEF ;LRCC Error - NRZI Mode NSG= 400 ;Non-standard Gap FCE= 1000 ;Frame Count Error CS= 2000 ;Correctable Skew - PE Mode ITM=CS ;Illegal Tape Mark - NRZI Mode NEF= 4000 ;Non-executable Function DTE= 10000 ;Drive Timing Error OPI= 20000 ;Operation Incomplete UNS= 40000 ;Drive Unsafe COR= 100000 ;Correctable Data - PE Mode CRC=COR ;CRC Error - NRZI Mode DAT= CS! PEF! INC ;Data Detection errors RHAS = +16 ;RH Attention Summary Register MTCK = +20 ;TM02/TM03 CRC or Dead Track Register MTDB = +22 ;TM02/TM03 Data Buffer MTMR = +24 ;TM02/TM03 Maintenance Register MTDT = +26 ;TM02/TM03 Drive Type Register MTSN = +30 ;TM02/TM03 Serial Number MTTC = +32 ;TM02/TM03 Tape Control Register TC.1600= 2000 ;1600 BPI TC.800= 1000 ;800 BPI TC.FMT= 300 ;Formatting Mode - PDP-11 normal assy/dissassy TC.EVN= 10 ;Even Parity .PAGE ; The following define bits in the Tape Characteristic Word (U.CW2). M.PEOV= 100000 ;Tape past Logical End of Volume M.AEOV= 40000 ;Tape at Logical End of Volume M.BOT= 20000 ;Tape at BOT M.1600= 4000 ;Tape Density Control; '1'=1600 BPI, '0'=800BPI M.HWL= 2000 ;Hardware Write Lock M.RWD= 1000 ;Unit is Rewinding M.SER= 400 ;Select Error - Tape Drive not accessible M.IXG= 200 ;Inhibit Write with Extended Interrecord Gap M.SWL= 100 ;Software Write Lock M.EOF= 40 ;Tape Mark detected (FWD direction only). M.EOT= 20 ;Tape at EOT M.EVN= 10 ;Even Parity USRBTS=4310 ; Bits Controlled by the User - ; M.1600! M.IXG! M.SWL! M.EVN NEWBTS=M.BOT!M.EOF!M.EOT ;Bits to be set before Call $IODON. ; Local Data ; ; Controller Impure Data Tables (Indexed by Subcontroller Number) ; ; Diagnostic Functions use bit 15 of RTTBL as a Flag for Interrupt Servicing. RTTBL: .BLKW T$$M03 ;Error Retry Count SPTBL: .BLKW T$$M03 ;Current Space Count - 2's. SPTOTL: .BLKW T$$M03 ;Total Blocks Spaced SPRMNG: .BLKW T$$M03 ;Remaining Space Count - 2's. FMTBL: .BLKW T$$M03 ;Format Code Save Area FCCDE: .BLKW T$$M03 ;Function Code Save Area CMDCNT: .BLKW T$$M03 ;Command Count Save Area BUFADR: .BLKW T$$M03 ;U.BUF Save Area DONADR: .BLKW T$$M03 ;DONTBL Address Save Area IOFCN: .BLKW T$$M03 ; > I/O Function. .PAGE ;+ ; VALID I/O FUNCTION TABLE ;- .MACRO DFENT FUNC,INDX,RQSTCD,RTRADR,RTRYCD .WORD FUNC ;I/O Function Code .BYTE INDX ;I/O Handling (Tables) Index .BYTE RQSTCD ;Device I/O Request Code .WORD RTRADR ;Tape Repositioned Return .WORD RTRYCD ;Device Error Recovery Request Code .ENDM ;DFENT LGFCN: DFENT IO.RLB,FREAD,FC.RED,RTYCMD,FC.SPR ;Read Forward DFENT IO.WLB,FWRTE,FC.WRT,RTYCMD,FC.ERS ;Write DFENT IO.RLV,FRREV,FC.REV,RTYCMD,FC.SPF ;Read Reverse DFENT IO.EOF,FWEOF,FC.WEF,RTYCMD,FC.ERS ;Write Tape Mark DFENT IO.ERS,FERSE,FC.ERS, 0, 0 ;Erase 3" Gap DFENT IO.RWD,FRWND,FC.RWD, 0, 0 ;Rewind DFENT IO.RWU,FRWDU,FC.RWU, 0, 0 ;Rewind Unload/Off-Line DFENT IO.SPB,FSPCR,FC.SPF,SPCONT,FC.SPR ;Space Blocks DFENT IO.SPF,FSPCF,FC.SPF,SPCONT,FC.SPR ;Space Files DFENT IO.STC,FSETC, 0, 0, 0 ;Set Char DFENT IO.SEC,FSENC, 0, 0, 0 ;Sense Char SMOU: DFENT IO.SMO,FSMOU, 0, 0, 0 ;Mount/Set Char ENDFCN=. LNGHT=.-SMOU .PAGE ; Function Code Index Table ; FREAD = 0 ;Read Logical Block FWRTE = 2 ;Write Logical Block FRREV = 4 ;Read Logical Block Reverse FWEOF = 6 ;Write Tape Mark FERSE = 10 ;Erase 3" Gap FRWND = 12 ;Rewind FRWDU = 14 ;Rewind Unload/Off-line FSPCR = 16 ;Space Blocks FSPCF = 20 ;Space Files FSETC = 22 ;Set Tape Characteristics FSENC = 24 ;Sense Tape Characteristics FSMOU = 26 ;Set and Mount Characteristics FRTRY = 30 ;Retry in Progress FSPRR = 22 ;Space Block Reverse FSPFR = 24 ;Space File Reverse ; Pre-initiation Processing Routines ; PRETBL: .WORD PRERED ;Read .WORD PREWRT ;Write .WORD PREREV ;Read Reverse .WORD PREEOF ;Write Tape Mark .WORD PREERS ;Erase 3" Gap .WORD PRECOM ;Rewind .WORD PRECOM ;Rewind Unload/Off-line .WORD PRESPC ;Space Blocks .WORD PRESPC ;Space Files .WORD PRESTC ;Set Characteristics .WORD PRESEC ;Sense Characteristics .WORD PRESMO ;Mount and Set Characteristics ; Succesful Completion Table ; DONTBL: .WORD REDDON ;Read Forward .WORD WRTDON ;Write Forward .WORD REVDON ;Read Reverse .WORD EOFDON ;Write Tape Mark .WORD EXTNST ;Erase 3" Gap .WORD RWDDON ;Rewind .WORD RWDDON ;Rewind Unload/Off-line .WORD SPFEXT ;Space Block Forward .WORD SPFEXT ;Space File Forward .WORD SPFEXT ;Space Block Reverse .WORD SPFEXT ;Space File Reverse .WORD SMODON ;IO.SMO Rewind Completion (TM03 problem) .WORD FATAL ;Error Recovery Completion .PAGE ; Mask Table - Retriable Errors ; DAT= CS! PEF! INC ERRMSK: .WORD COR! DTE! DAT! FCE! FMT! CPR ;Read Forward .WORD COR! DTE! DAT! FCE! FMT! CPR! NSG! DPR ;Write .WORD COR! DTE! DAT! FCE! FMT! CPR! OPI ;Read Reverse .WORD COR! DAT! CPR! NSG ;Write TMK .WORD 0 ;Erase 3" Gap .WORD FMT! NEF ;Rewind .WORD FMT! NEF ;Rewind Unl/Offline .WORD FCE! OPI ;Space FWD Blocks .WORD FCE! OPI ;Space FWD Files .WORD FCE! OPI ;Space REV Blocks .WORD FCE! OPI ;Space REV Files .WORD 0 ;No Function .WORD 0 ;Retry ; Retry Table; > Error Recovery RETRY Entry Points ; RTYTBL: .WORD REDRTY ;Read Forward .WORD WRTRTY ;Write .WORD REVRTY ;Read Reverse .WORD WRTRTY ;Write Tape Mark .WORD FATAL ;Erase - Not Retriable .WORD RWDRTY ;Rewind .WORD RWDRTY ;Rewind Unload/Off-line .WORD SPRRTY ;Space FWD Blocks .WORD SPFRTY ;Space FWD Files .WORD SPRRTY ;Space REV Blocks .WORD SPFRTY ;Space REV Files .WORD FATAL ;IO.SMO Rewind not retriable (TM03 problem) .WORD FATAL ;Error during Error Recovery - Not Retriable. ; Error Check Table; > Specific Function, ERROR CHECK Entry Points ; CHKTBL: .WORD REDERR ;Read Forward .WORD COMRTY ;Write .WORD REVERR ;Read Reverse .WORD COMRTY ;Write Tape Mark .WORD FATAL ;Erase 3" Gap - Fatal .WORD RWDRTY ;Rewind .WORD RWDRTY ;Rewind Unload/Off-line .WORD SPFEXT ;Space FWD Blocks .WORD SPFEXT ;Space FWD Files .WORD SPRERR ;Space REV Blocks .WORD SPRERR ;Space REV Files .WORD FATAL ;IO.SMO Rewind - Fatal (TM03 problem) .WORD RTYCON ;Retry Frame Count Errors .PAGE ; Driver Dispatch Table ; DDT$ MM,T$$M03 ;Create the Driver Dispatch Table. ;+ ; **-MMINI-RH11/RH70 TM02/TM03 Magnetic Tape Controller Initiator ; ; This Routine is entered from the Queue I/O directive when an I/O ; Request is queued and at the end of a previous I/O operation to pro- ; pagate the execution of the driver. If the specified Controller is ; not busy, then an attempt is made to dequeue the next I/O request. ; Else a return to the caller is executed. If the dequeue attempt is ; successful, then the next I/O operation is initiated. A return to the ; caller is then executed. If this unit is currently doing a ; rewind any requests for it are rejected by the 'Acceptance' ; routine. These requests will be done when the rewind is ; complete ; ; ; Inputs: ; ; R5=Address of the UCB of the Controller to be Initiated. ; ; Outputs: ; ; If the specified controller is not busy and an I/O request is ; waiting to be processed, then the request is dequeued and the I/O ; operation is initiated. ;- MMINI: GTPKT$ MM,T$$M03 ;Get an I/O packet to process ; ; The Following Arguments Are Returned ; ; R1 > I/O request packet. ; R2 = Physical Unit Number of requested TM02/3. ; R3 = RH Controller Index. ; R4 > Status Control Block. ; R5 > Tape Drive UCB. ; ; RH11/RH70 TM02/TM03 Magnetic Tape Function Independent I/O Request ; Packet Format: ; ; WD. 00 -- I/O queue thread word. ; WD. 01 -- Request priority, event flag number. ; WD. 02 -- Address of the TCB of the requestor task. ; WD. 03 -- Pointer to second LUN word in requestor task head ; WD. 04 -- Contents of the first LUN word in requestor task header ; WD. 05 -- I/O function code (IO.RLB/IO.RWD/IO.SPB/IO.SPF/IO.EOF) ; WD. 06 -- Virtual address of I/O status block. ; WD. 07 -- Relocation bias of I/O status block. ; WD. 10 -- I/O status block address (Displacement + 140000) ; WD. 11 -- Virtual address of AST service routine. ; 10$: CALL $RQSUB ;Request the Subcontroller. MOV U.KRB1(R5),R2 ;R2 > KRB1. MOVB K1.CON(R2),R3 ;R3 - Formatter Unit Number, ASL R3 ; Convert to Word Index. MOV S.PKT(R4),R1 ;R1 > I/O Packet. MOV #LGFCN,R2 ;R2 > Valid I/O Function Table. MOV I.FCN(R1),R0 ;R0 - QIO Function Code. BICB #US.SUP,U.STS(R5) ;Error Recovery allowed. CLRB RTTBL+1(R3) ;Clear Diagnostic Flag. BITB #IQ.UMD,R0 ;Diagnostic Function? BEQ 20$ ;IF EQ, No. MOV #100000,RTTBL(R3) ;Indicate Diagnostics, BISB #US.SUP,U.STS(R5) ; no Error Recovery. 20$: BITB #IQ.X,R0 ;Error Recovery allowed? BEQ 25$ ;IF EQ, No. BISB #US.SUP,U.STS(R5) ;No Error Recovery. 25$: BICB #IQ.X!IQ.UMD!IQ.Q,R0 ;R0 - Function Code for Validation. 30$: CMP R0,(R2) ;Function Code match? BEQ 50$ ;IF EQ, Yes. ADD #LNGHT,R2 ;Next I/O Function. CMP R2,#ENDFCN ;End of table? BLO 30$ ;IF LO, No. Check next entry. 40$: MOV #IE.IFC&377,R0 ;Yes - Illegal Function. CALL $RLSUB ;Release the Subcontroller. CALL $IOALT ;End this Request and BR MMINI ; service other outstanding Requests. 50$: MOV R2,IOFCN(R3) ;Remember I/O Request TST (R2)+ ; and MOV (R2),U.FCDE(R5) ; QIO index. CLR SPTBL(R3) ;Clear out Spacing Indicator. TST RTTBL(R3) ;Diagnostic Function? BMI 60$ ;IF MI, Yes - Inhibit Retries. MOV #RETRY,RTTBL(R3) ;Set Retry Count. ; Request the Controller ; 60$: CMPB U.FCDE(R5),#FRREV ;Data Transfer Function? BLOS 70$ ;IF LOS, Yes. CALL $RQCNC ;Request Controller for Control Fnct. BR 80$ ;Perform request. 70$: CALL $RQCND ;Request Controller for Dt Trnsfr Fnct. 80$: MOV U.KRB1(R5),R3 ;R3 > KRB1. CALL SELECT ;Update Device Tape Char Info. MOVB U.FCDE(R5),R0 ;R0 - QIO Index, I/O Function Code. MOV S.PKT(R4),R1 ;R1 > I/O Packet. MOVB K1.CON(R3),R3 ;R3 - Formatter Unit Number, ASL R3 ; Convert to Word Index. MOV #FATAL,DONTBL+FRTRY ;Preset Error Address. JMP @PRETBL(R0) ;Preprocess I/O Request. .PAGE ;+ ; **-PRESPC - Preprocess Space Function Request ; ; This routine Pre-Process's Space Requests. ; ; Spacing Function Dependent I/O Packet Format: ; ; WD. 12 -- Spacing Count (positive=forward, Negative=backward). ; WD. 13 -- Not Used. ; WD. 14 -- Not Used. ; WD. 15 -- Not Used. ; WD. 16 -- Not Used. ; WD. 17 -- Relocation Bias Of Diagnostic Reg. Buffer Address ; WD. 20 -- Diag. Reg. Buffer Address (Displ. + 140000) ;- PRESPC: MOV #IS.SUC&377,R0 ;Assume 0 Space Count and CLR SPTOTL(R3) ; indicate No Blocks Spaced yet. MOV U.BUF(R5),-(SP) ;Current Space Count. BEQ 40$ ;IF EQ, Done. BMI 10$ ;IF MI, Space REV. ;Space FWD MOV #IE.EOV&377,R0 ;May be at EOV BIT #M.AEOV,U.CW2(R5) ;At EOV? BNE 40$ ;IF NE, Yes - can't Space FWD from here NEG (SP) ;I/O Space Count - 2's complement. BR 20$ ;Continue ;Space REV 10$: BIC #M.AEOV,U.CW2(R5) ;Clear at End of Volume status. MOVB #FC.SPR,U.FCDE+1(R5) ;Space REV Function and ADD #4,U.FCDE(R5) ; Space REV Function Index. 20$: CLR U.BUF(R5) ;Init for Function Code CMP #IO.SPF,@IOFCN(R3) ;Space Files? BNE 30$ ;IF NE, No. MOV (SP),SPRMNG(R3) ;Remaining Spacing Count - 2's. MOV (SP),I.PRM+4(R1) ;Save for later calculations. MOV #1,(SP) ;Set for MAX Space Count. 30$: MOV (SP),U.CNT(R5) ;Current I/O Space Count. MOV (SP)+,SPTBL(R3) ;Save for Timeout situation. BR PWFTST ;Start I/O if no PWFLD Indication. 40$: TST (SP)+ ;Clean up Stack for Return. JMP EXTNST ;End Request. .PAGE ;+ ; **-PRESMO - IF Tape at BOT, Set Tape Characteristics per User Request. ;- PRESMO: BIT #M.BOT,U.CW2(R5) ;Tape at BOT? BNE SMORWD ;IF NE, Yes - Set Tape Characteristics. MOV #IE.FHE&377,R0 ;No, Fatal Error - BR PREXIT ;End Request. ;+ ; **-SMORWD - Issue REWIND to clear possibly hung EOT status in TM03's. ; Caused by manually rewinding an Online Tape Unit previously at EOT. ;- SMORWD: BIC #M.AEOV,U.CW2(R5) ;Not at End of Volume Status. BIC #USRBTS!7,U.CW2(R5) ;Prepare for BIC #^C,U.BUF(R5) ; User Controlled Bits. BIS U.BUF(R5),U.CW2(R5) ;Set User Controlled Characteristics. MOV #FC.RWD,U.BUF(R5) ;Set and JMP PRCOM ; request I/O REWIND. SMODON: BICB #US.PWF,U.STS(R5) ;Clear PWFLD Status. CALL SELECT ;Update Tape Char Word BR PRESEC ; and end IO.SMO Request. ;+ ; **-PRESTC - Set Characteristics Command ; Sets User Controlled Bits in Tape Characteristics Word. ;- PRESTC: BIC #USRBTS!7,U.CW2(R5) ;Prepare for BIC #^C,U.BUF(R5) ; User Controlled Bits. BIS U.BUF(R5),U.CW2(R5) ;Set User controlled Characteristics. ;+ ; **-PRESEC - Return Tape Characteristics Word ;- PRESEC: BIC #M.PEOV,U.CW2(R5) ;No M.PEOV for IO.SMO request. MOV U.CW2(R5),R1 ;Return Tape Characteristic's MOV #IS.SUC&377,R0 ; and indicate Success. PREXIT: JMP EXIT ;End Request. .PAGE ;+ ; **-PREWRT - WRITE Request Preprocessing: ; Verify At least Minimum Record Size .and. Write Enabled. ;- PREWRT: MOV #IE.SPC&377,R0 ;Assume Parameter Problems CMP #MINREC,I.PRM+4(R1) ;Minimum Record Size? BHI PREEXT ;IF HI, Record too small. ;+ ; **-PREEOF - Write Tape Mark Preprocessing: ; **-PREERS - 3" Gap Erasure Preprocessing: ; Verify Write Enabled. ;- PREEOF: PREERS: MOV #IE.WLK&377,R0 ;Assume Write Locked BIT #M.SWL!M.HWL,U.CW2(R5) ;Write Locked? BNE PREEXT ;IF NE, Yes. CMPB #FRREV,U.FCDE(R5) ;Data Transfer? BLT PWFTST ;IF LT, No. ;+ ; **-PRERED - Read Forward and ; PREREV - Read Reverse Preprocessing: ;- PRERED: PREREV: MOV S.KRB(R4),R1 ;Retrieve KRB Address. BIT #FE.EXT,$FMASK ;22-bit Addressing enabled? BEQ 5$ ;IF EQ, No. BIT #KS.MBC,K.STS(R1) ;MASSBUS Device? BNE 5$ ;IF NE, Yes. CALL $STMAP ;Setup Unibus Map. ASL U.BUF(R5) ;Shift bits <4:5> ASL U.BUF(R5) ; into bits <8:9>. ASL U.BUF(R5) ; ... ASL U.BUF(R5) ; ... CALL $MPUBM ;Setup UMR's for transfer MOV @S.KRB(R4),R2 ; and restore R2 (=CSR). 5$: MOV R5,R1 ;R1 > ADD #U.BUF,R1 ; U.BUF. BIT #FE.EXT,$FMASK ;22-bit Addressing? BNE 10$ ;IF NE, Yes. ROL (R1) ; Setup ROL (R1) ; A17, A16 ROL (R1) ; into ROL (R1) ; Hi Byte. 10$: CMPB #4,U.FCDE(R5) ;Read Reverse? BNE PWFTST ;IF NE, No. SUB #2,U.CNT(R5) ;Read reverse - ADD U.CNT(R5),2(R1) ; Adjust Buffer Pointer BCC 15$ ; to end of ADCB 1(R1) ; Buffer Area. 15$: ADD #2,U.CNT(R5) ;Restore Transfer Count. PWFTST: MOV #IE.ABO&377,R0 ;Request Aborted IF PWFLD Status BITB #US.PWF,U.STS(R5) ;Power Fail occur? BEQ PRECOM ;IF EQ, No - Continue PREEXT: JMP EXTNST ;Else - End Request. ;+ ; **-PRECOM - Common Preprocessing Entry ; ; All requests have been preprocessed successfully. ; Setup Formatter Mode Control and ; Subsequently perform I/O Function Execution. ;- PRECOM: MOVB U.FCDE+1(R5),U.BUF(R5) ;Retrieve Function. PRCOM: MOVB U.SNUM(R5),R0 ;Tape Unit #. BIS #TC.1600,R0 ;Assume 1600 BPI. BIT #M.1600,U.CW2(R5) ;Assumption correct? BNE 10$ ;IF NE, Yes. BIC #TC.1600,R0 ;Setup for BIS #TC.800,R0 ; 800 BPI. BIT #M.EVN,U.CW2(R5) ;Even Parity Mode? BEQ 10$ ;IF EQ, No. BIS #TC.EVN,R0 ;Even Parity Mode. 10$: BIS #TC.FMT,R0 ;Normal Assys/Disassy of Data. MOV R0,FMTBL(R3) ;Tape Drive Control Mode. ;+ ; **-FNCEX - Function Execution ; ; Issue I/O Function. RH Controller, Tape Formatter and Tape Drive ; ownership need be synchronized before I/O may proceed. ; ; Inputs: ; R2 = CSR Address R4 > SCB. ; R3 = Formatter Index R5 > UCB. ;- FNCEX: BIT #M.SER,U.CW2(R5) ;Select Error? BNE SELERR ;IF NE, Yes - Select Error. BIT #PIP,MTDS(R2) ;Tape moving? BEQ 10$ ;IF EQ, No. JMP WTRWD ;Wait until Tape Stops. 10$: MOV DONTBL+FRTRY,DONADR(R3) ; > Retry Completion. MTPS #PR5 ;Inhibit Interrupts. CALL SELDRV ;;Select Formatter. MOV FMTBL(R3),MTTC(R2) ;;Select Tape Drive/Formatting mode. MOV #TRE!FC.CLR,(R2) ;;Clear Formatter. MOV U.CNT(R5),MTFC(R2) ;;Setup Command Count. BIC #M.AEOV!M.SER!M.RWD,U.CW2(R5) ;;Clear status bits. CMPB U.FCDE(R5),#FRREV ;;Data Transfer Function? BLOS 20$ ;;IF LOS, Yes. BISB #S3.SIP,S.ST3(R4) ;;Positioning in Progress. BR 25$ ;;Issue I/O Function. 20$: NEG MTFC(R2) ;;Formatter Frame Count - 2's cmplmnt. MOV MTFC(R2),RHWC(R2) ;;RH Controller ROR RHWC(R2) ;; Word Count. MOV U.BUF+2(R5),RHBA(R2) ;;Low order 16 bit address. MOV S.KRB(R4),R1 ;; > KRB. BIS #KS.DIP,K.STS(R1) ;;Data Transfer in Progress. BIT #FE.EXT,$FMASK ;;22-bit Addressing? BEQ 30$ ;;IF EQ, No. BIT #KS.MBC,K.STS(R1) ;;MASSBUS Device? BEQ 30$ ;;IF EQ, No. ADD K.OFF(R1),R1 ;; > to UCB table and MOV KE.RHB(R1),R1 ;; obtain RHBAE Offset. ADD R2,R1 ;;Form I/O page address. MOVB U.BUF+1(R5),(R1) ;;HI Order address bits to RHBAE reg. 25$: MOVB U.BUF(R5),(R2) ;;Start I/O. BR 40$ ;;.. Cont. 30$: MOV U.BUF(R5),(R2) ;;Start I/O. 40$: MOV U.KRB1(R5),R2 ;; R2 > KRB1 INC K1.STS(R2) ;; K1.STS .NE. BIS #S2.ACT,S.ST2(R4) ;; I/O active. BICB #S3.SPU,S.ST3(R4) ;;Clear Spin-Up indication. MOVB S.ITM(R4),S.CTM(R4) ;;Start Timeout Count. CLR S.FRK+2(R4) ;;Reset Fork Interlock. MTPS #PR0 ;;Allow Interrupts. RETURN ;+ ; **-SELERR-Issue Select Error Message ; ; IF Not Diagnostic or ACP - Issue a Select Error Message to the ; System Console Terminal every 15 seconds ; (the unit is subsequently checked once a second) ; until Tape Drive comes ready or Request Aborted. ;- SELERR: MOV #IE.DNR&377,R0 ;Assume Not Ready Status. BITB #US.SUP,U.STS(R5) ;User Mode Diagnostics or IQ.X? BNE 5$ ;IF NE, Yes - End Request. TST U.ACP(R5) ;End Request if associated ACP? BEQ 10$ ;IF EQ, No. 5$: JMP EXTNST ;End Request - Device Not Ready 10$: CALL RLSDRV ;Release Tape Drive, CALL $RLSUB ; TM Subcontroller CALL $RLCN ; and RH Controller. DECB S.STS(R4) ;Time for a 'Select Error' message? BNE TIMER ;IF NE, No. MOV #T.NDSE,R0 ;Set up Error Message Code MOVB #15.,S.STS(R4) ; and set up 15 sec Timeout. CALL $DVMSG ;Send the Error Message to Sys Consl. TIMER: MOVB #1,S.CTM(R4) ;Set up a Timeout. TIMER1: CLR S.FRK+2(R4) ;Reset Fork Interlock. RETURN ;Wait for Timeout. .PAGE ;+ ; **-MMOUT - Device Timeout Entry Point ; ; I/O Timeouts may be caused by Powerfailure or other Hardware considerations. ; ; TIMEOUT CONSIDERATIONS: ; ; 1. An RH Controller supports Parallel Operation and requires Concurrent ; Operation synchronization. An RH supports one current Drive Data ; Transfer Operation overlapped with other Drive(s) Non Data Transfers. ; There may be further restrictions on each Drive - i.e. Spacing Operations ; on a given Drive may not overlap Data Transfers on the same Drive. ; ; 2. The RH Controller is operated with Interrupt ENABLED - this may result ; in an Interrupt occuring simultaneously with Driver being called at ; Timeout Entry point. The Interrupt may be from some external event, ; such as a RWD completing, or a Tape Drive coming Online. ; ; The Driver must be prepared for such an occurence - this is done by the ; interlock S.FRK+2; IF S.FRK+2 is Zero, Interrupt processing is allowed. ; ; 3. Another problem exists when a Driver has QUD a Fork while the Exec ; was sequencing to the same Driver's Timeout Entry Point. Timeout Entry ; code sequences with a Fork Block currently in the Fork Queue. ; ; Inputs: ; R4 > SCB. R5 > UCB. ;- .ENABL LSB MMOUT: TST S.FRK+2(R4) ;;;Interrupt handling I/O ? BEQ 10$ ;;;IF EQ, No - Device timed out. RETURN ;;;Interrupt will handle it. 10$: INC S.FRK+2(R4) ;;;Timeout will handle it. MTPS #PR0 ;;;Allow interrupts. CALL $RQSUB ;Request Subcontroller. CMPB #FRREV,U.FCDE(R5) ;Data Transfer? BLT 20$ ;IF LT, No. CALL $RQCND ;Request Controller for DT XFR Function BR 30$ ; .. Continue 20$: CALL $RQCNC ;Request Controller for Cntrl Function 30$: MOV U.KRB1(R5),R3 ;R3 - MOVB K1.CON(R3),R3 ; Subcontroller ASL R3 ; as Word Index. CALL SELDRV ;Select Subcontroller. MOV #IE.DNR&377,R0 ;Assume Not Ready Status. BIT #M.RWD,U.CW2(R5) ;Tape Drive in previous Rewind? BEQ 40$ ;IF EQ, No. ; Tape Drive in previous RWD. BITB #US.ABO,U.STS(R5) ;Abort Request? BNE 53$ ;IF NE, Yes - End current Request. CALL SELECT ;Tape Drive available for Request? 35$: BCS SELERR ;IF CS, No - Issue 'Select Error' Msg. BIT #M.RWD,U.CW2(R5) ;Tape Drive - still RWD mode? BEQ 60$ ;IF EQ, No - Start current Request. WTRWD: CALL RLSDRV ;ELSE Release the Tape Drive, CALL $RLSUB ; Subcontroller and CALL $RLCN ; RH Controller. BR TIMER ;Wait for one second. ; Tape Drive had I/O previously started. 40$: MOV SPTBL(R3),R1 ;Spacing via BLKS/TMK? BEQ 52$ ;IF EQ, No. CMP R1,MTFC(R2) ;Blank tape? BEQ 50$ ;IF EQ, Yes. End Rqst(Can't Stop Tp Sp) MOV MTFC(R2),SPTBL(R3) ;Remember Blocks/TMK's spaced. MOVB S.ITM(R4),S.CTM(R4) ;Wait BR TIMER1 ; some more. ; Device I/O Timeout - Current I/O Not Completed in reasonable time. 50$: CALL $DVTMO ;Log Device Timeout. BCS 80$ ;IF CS, Diagnostic Function. JMP FATAL ;End Request - Space Timeouts Fatal. 52$: BITB #US.ABO,U.STS(R5) ;Abort Request? BEQ 55$ ;IF EQ, No. 53$: MOV #IE.ABO&377,R0 ;Indicate Aborting BR 90$ ; and end Request. ; Timeouts are not retried because the tape position is unknown. ; 55$: BIT #M.SER,U.CW2(R5) ;Select Error? BEQ 50$ ;IF EQ, No - Error. CALL SELECT ;Ready yet? BCS 35$ ;IF CS, No. 60$: JMP PRECOM ;Retry Request. ; The following handles a timeout during a diagnostic function. ; 80$: CALL SELDRV ;Select Subcontroller/Tape Drive. CALL MMDINT ;Pass Device Registers. ; NOTE: The following may cause all I/O on other Drive(s) attached to ; the same RH Controller to abort. Other I/O requests will be handled ; by their respective Driver Timeout handling. ; *** Exception - Tape Spacing operations. ; MOV #SCLR,RHCS2(R2) ;RH Subsystem Clear - ; Stop all I/O on that RH Controller. CALL SELECT ;Select Subcontroller/Tape Drive 90$: JMP EXTNST ; and Request. .DSABL LSB .PAGE ;+ ; **-MMCAN - Cancel I/O Request ;- MMCAN: CMP I.TCB(R0),R1 ;Cancel I/O Request for issuing Task? BNE 10$ ;IF NE, No. BISB #US.ABO,U.STS(R5) ;Indicate I/O Request be Aborted. 10$: RETURN ;+ ; **-MMPWF - Power Fail Recovery ; ; Powerfail is handled via the Device Timeout Facility - to avoid a race ; condition that could exist in restarting the I/O Operation. ;- MMPWF: BCS 10$ ;IF CS, Controller Power Fail. BISB #US.PWF,U.STS(R5) ; ELSE, Unit Power Fail 10$: RETURN ; Disallow normal QIO'S. ;+ ; **-MMINT RH11/RH70 TM02/TM03 Interrupt service routine. ; ; R3 > KRB R5 > UCB (owner) - data transfer interrupt ; R5 > UCB (1st slave) - other interrupts ;- $MMINT::NOP ;;; MOV U.KRB1(R5),R4 ;;;R4 > KRB1. MOV K1.OWN(R4),R5 ;;;R5 > UCB. BNE 10$ ;;;IF NE - Owner exists. MOV (R4),R5 ;;;Use Subcontroller's Tape Drive UCB. 10$: MOV U.SCB(R5),R4 ;;;R4 > SCB. TST S.FRK+2(R4) ;;;Fork Block in use? BNE 18$ ;;;IF NE, Yes. Disregard Interrupt. ; If data transfer - service interrupt BIT #KS.DIP,K.STS(R3) ;;;Data trfr in prog? BNE 13$ ;;;IF NE, Yes - service intrpt. ; If interrupt not during non-data I/O - discard it. MOV U.KRB1(R5),R2 ;;;R2 > KRB1 TST K1.STS(R2) ;;;Started I/O? BEQ 14$ ;;;IF EQ, No. ; Interrupt from SSC and non-data I/O complete asynchronously. MOV (R3),R2 ;;;R2 - CSR. ; If non-data I/O complete - service interrupt. BIT #PIP,MTDS(R2) ;;;Non-data I/O complete? BEQ 13$ ;;;IF EQ, Yes. MOV (R2),-(SP) ;;;Isolate I/O BIC #^C<77>,(SP) ;;; Command Code. CMP #6,(SP)+ ;;;Just completed RWD? BEQ 13$ ;;;IF EQ, yes - RWD initiated. ; If SSC interrupt - discard it. BIT #SSC,MTDS(R2) ;;;SSC condition? BNE 14$ ;;;IF NE, Yes. 13$: CALL $FORK ;;;Create a system process. MOV U.KRB1(R5),R1 ;R1 > KRB1. CLR K1.STS(R1) ;K1.STS .EQ. I/O over. TST K1.OWN(R1) ;Owned? BNE 20$ ;IF NE, Yes - Solicited Interrupt. ; Presently Unsolicited Interrupts are disregarded. 14$: CALL $RQSUB ;Request the Subcontroller, CALL $RQCNC ; Controller and CALL SELDRV ; Formatter/Tape Drive. BIT #M.RWD!M.SER,U.CW2(R5) ;Previously Rewinding or Select Error? BEQ 15$ ;IF EQ, No. INCB S.CTM(R4) ;Timeout Count - per original value. 15$: CALL RLSDRV ;Release Tape Drive, CALL $RLSUB ; Subcontroller CALL $RLCN ; and RH Controller. CLR S.FRK+2(R4) ;Reset Fork interlock and 18$: RETURN ; discard Unsolicited Interupt. 20$: BICB #S3.SIP,S.ST3(R4) ;I/O not in progress. BITB #US.ABO,U.STS(R5) ;Abort Request? BEQ 25$ ;IF EQ, No. MOV #IE.ABO&377,R0 ;Aborting BR ENDRQS ; Request. 25$: MOV #IS.SUC&377,R0 ;Assume Success MOVB K1.CON(R1),R3 ;Retrieve Formatter Number ASL R3 ; and make Word Index. MOV DONADR(R3),DONTBL+FRTRY ;Set Retry done Address. MOVB U.FCDE(R5),R1 ;Retrieve Function Index. BIT #M.EOF!M.BOT,U.CW2(R5) ;Tape Mark seen last time? BEQ 40$ ;IF EQ, No. BIS #M.PEOV,U.CW2(R5) ;Set for EOV check. 40$: BIC #NEWBTS,U.CW2(R5) ;Status bits that may have changed. CALL SELECT ;Select subcontroller/tape unit. BIT #TRE,(R2) ;RH Transfer Error? BNE 50$ ;IF NE, Yes. 45$: BIT #ERR,MTDS(R2) ;Tape Drive Error? BNE 60$ ;IF NE, Yes. JMP @DONTBL(R1) ;No I/O Error - End Request. ; RH Controller Transfer Error - 50$: BIT #CPE,(R2) ;Parr Err, MASSBUS Control Bus? BNE FATAL ;IF NE, Yes - Unrecoverable. MOV RHCS2(R2),R0 ;R0 - Possible BIC #^C,R0 ; RH Error Indication. BEQ 60$ ;IF EQ, No. BIT #DLT!UPE!DPE,R0 ;Repositioning Error? BNE 67$ ;IF NE, Yes. BIT #PGE!NED,R0 ;Retry Error? BNE 57$ ;IF NE, Yes. BIT #MXF,R0 ;Missed Transfer? BEQ 53$ ;IF EQ, No. CMPB #4,U.FCDE(R5) ;Read Reverse? BNE 57$ ;IF NE, No. BIT #M.BOT,U.CW2(R5) ;BOT during Read Reverse? BEQ 57$ ;IF EQ, No. BR 45$ ; .. Check for Tape Drive Error. 53$: BIT #WCE,R0 ;Write Check Error? BNE FATAL ;IF NE, Yes. (Else, C2.NEM) 55$: MOV U.CNT(R5),R0 ;R0 - Frame Count NEG R0 ; Request. ADD MTFC(R2),R0 ;Frame Count as Requested? BNE 67$ ;IF NE, Moved. 57$: CALL LOGERR ;Log Error JMP FNCEX ;Reissue Request. ; Drive Error Indication - Determine IF Recoverable 60$: MOV MTER(R2),R0 ;R0 - Error Register BIT ERRMSK(R1),R0 ;Recoverable Error? BEQ FATAL ;IF EQ, No. BIT #FMT!CPR!DTE,R0 ;Positioning Known? BNE 55$ ;IF NE, No. 65$: BIT #MOL,MTDS(R2) ;Drive Ready? BEQ FATAL ;IF EQ, No - Fatal. 67$: MOV MTER(R2),R0 ;R0 - Error Register. JMP @CHKTBL(R1) ;Recover per Specific I/O Request. ; Unrecoverable Request - End Request FATAL: CALL LOGERR ;Log Error. MOV #IE.FHE&377,R0 ;Unrecoverable Error. ENDRQS: JMP EXTNST ;End Request. .PAGE ;+ ; **-REVERR - Read Reverse Special Error Checking ; ; Test for Read Reverse into BOT. ; IF BOT THEN IS.SUC and Zero Byte Count. ;- .ENABL LSB REVERR: BIT #OPI,R0 ;Operation Incomplete? BEQ REDERR ;IF EQ, No - Not a BOT Condition BIT #BOT,MTDS(R2) ;Tape at BOT? BEQ FATAL ;IF EQ, No - Errors are Fatal. BIS #M.BOT,U.CW2(R5) ;Indicate BOT Status. CLR MTFC(R2) ;No Data Transferred. BR 50$ ;End Request. ;+ ; **-REDERR - Read Error Checking ;- REDERR: BIT #INC!PEF!DTE!FMT!CPR,R0 ;Retry Error? BNE 20$ ;IF NE, Yes. BIT #FCE,R0 ;Frame Count Error? BNE 30$ ;IF NE, Yes. 10$: BIT #PES,MTDS(R2) ;PE Tape? BNE 40$ ;IF NE, Yes - Corrected Data. 20$: JMP COMRTY ;Retry Request. 30$: BIT #TM,MTDS(R2) ;Tape Mark? BEQ 50$ ;IF EQ, No. MOV #IE.EOF&377,R0 ;EOF Ending Status. BIS #M.EOF,U.CW2(R5) ;Indicate EOF in Characteristics Word. BR 60$ ;End Request. 40$: CALL LOGERR ;Log Error. 50$: MOV #IS.SUC&377,R0 ;Indicate Sucess 60$: JMP @DONTBL(R1) ; and End Request. .DSABL LSB ;+ ; **-RWDERR/RWDRTY - Rewind .OR. Unload/Offline Error Retry ;- RWDERR: RWDRTY: BIC #M.1600,U.CW2(R5) ;Setup for 800BPI. BIT #TC.1600,FMTBL(R3) ;Last Request at 1600BPI? BNE 10$ ;IF NE, Yes - Try 800BPI. BIS #M.1600,U.CW2(R5) ;Setup to try at 1600BPI. 10$: CMP #RETRY,RTTBL(R3) ;Retried at least once? BNE FATAL ;IF NE, Yes. DECB RTTBL(R3) ;Retry JMP PRCOM ; only once. .PAGE ;+ ; **-SPRERR - Space Reverse - Error Handling ;- .ENABL LSB SPRERR: BIT #BOT,MTDS(R2) ;BOT Encountered? BEQ SPFEXT ;IF EQ, No. BIS #M.BOT,U.CW2(R5) ;Indicate BOT Status. MOV #IS.SUC&377,R0 ;Indicate Success BR 30$ ; and End Request. ;+ ; **-SPFEXT - Space Forward - Error Handling ; Space Functions - Completion Routines ;- SPFEXT: BIT #OPI,R0 ;Operation Incomplete? BNE FATAL ;IF NE, Yes - Fatal Error. MOV #IS.SUC&377,R0 ;Indicate Success 10$: BIT #TM,MTDS(R2) ;Detected Tapemark? BEQ 30$ ;IF EQ, No. MOV #IE.EOF&377,R0 ;Indicate Tapemark Status. CALL CHKEOV ;Check for End of Volume. BCC 15$ ;IF CC, Not EOV. MOVB #FRTRY,U.FCDE(R5) ;Set for Backspace. JMP BACK ;Backspace One Record. 15$: JMP @RTYTBL(R1) ;Any more files? SPCONT: CLR U.CNT(R5) ;Clear Requested Count for Calc MOV #IE.EOV&377,R0 ;Assume EOV ending. BIS #M.AEOV,U.CW2(R5) ;Indicate EOV status. 30$: MOV S.PKT(R4),R1 ;Get I/O Packet Address. CMPB #IO.SPF,I.FCN(R1) ;Space Files? BEQ SPFDON ;Yes - Endup Files Completion. ; This works because we only get to SPRRTY: for successful completion ; of the backup (Also MTFC=0), and IO.SPB cannot detect EOV after ; spacing over any blocks. (IO.SPF Doesn't Use U.CNT) ; ;Space Blocks - FWD/REV ; SPRRTY: TST MTFC(R2) ;Enough Blocks Spaced? BEQ 35$ ;Yes - End Request. BIT #TM!BOT,MTDS(R2) ;TMK or BOT seen? BNE 35$ ;Yes - End Request. MOV U.CNT(R5),R0 ;Retrieve Requested Count. SUB MTFC(R2),R0 ;Calculate actual number spaced. ADD R0,SPTOTL(R3) ;Add it to total spaced. MOV MTFC(R2),U.CNT(R5) ;Update Current Count MOV MTFC(R2),SPTBL(R3) ; and save it for timeout. BR 70$ ;Try to Space some more. 35$: MOV U.CNT(R5),R1 ;Retrieve Requested Count. SUB MTFC(R2),R1 ;Calculate actual number spaced. ADD SPTOTL(R3),R1 ;Additional Space Operations ; done IF after EOT. BR 60$ ;Exit. ;+ ; **-SPFRTY - Space Files FWD/REV ;- SPFRTY: INC SPRMNG(R3) ;Done? BNE 70$ ;IF NE, No - Continue. MOV #IS.SUC&377,R0 ;Indicate Success, BR 50$ ; Setup count and End Request. SPFDON: BIT #BOT!TM,MTDS(R2) ;BOT or TMK? BEQ 70$ ;IF EQ, No - Continue. BIT #BOT,MTDS(R2) ;Stopped for BOT or EOV? BNE 50$ ;Don't increment the count BIT #M.AEOV,U.CW2(R5) ; because we didn't BNE 50$ ; pass a file. INC SPRMNG(R3) ;Increment TMK Count. 50$: MOV S.PKT(R4),R1 ;Get I/O Packet Address. MOV I.PRM+4(R1),R1 ;Retreive Count Requested. SUB SPRMNG(R3),R1 ;Subtract Number remaining. 60$: NEG R1 ;Set for positive Return Value. JMP EXIT ;End Request. 70$: JMP FNCEX .DSABL LSB ;+ ; **-COMRTY - Common Retry Routine ; ; IF Retries Suppressed - End Request ; ELSE Call Function Specific Retry Routine ;- COMRTY: CALL LOGERR ;Log the Error MOVB U.FCDE(R5),R1 ;R1 - Function Index BITB #US.SUP,U.STS(R5) ;Retries allowed? BNE 10$ ;IF NE, No - End Request. DECB RTTBL(R3) ;Any more Retries left? BLE 10$ ;IF LE, No - End Request. MOV U.FCDE(R5),FCCDE(R3) ;Save Function Index MOV U.CNT(R5),CMDCNT(R3) ;Save Command Count MOV U.BUF(R5),BUFADR(R3) ;Save Buffer Address MOVB #FRTRY,U.FCDE(R5) ;Set Retry Command JMP @RTYTBL(R1) ;GOTO Function Specific Retry routine 10$: BIT #PEF!OPI,R0 ;Tape Format Error? BEQ RTYCN1 ;IF EQ, No. MOV #IE.BBE&377,R0 ;Other Error. RTYCON: JMP @DONTBL(R1) ;End Request. RTYCN1: MOV #IE.VER&377,R0 ;Request Return Code. BR RTYCON ;End Request. .PAGE ;+ ; -- Write/WTMK Retry -- ;- .ENABL LSB WRTRTY: MOV #FRTRY,R1 ;R1- Retry Index. MOV #RTNWRT,DONTBL(R1) ;I/O Cont after Reposition. MOV #FC.SPR,U.BUF(R5) ;Setup I/O Request Code. BR 15$ ;Reposition Tape. RTNWRT: BIT #M.IXG,U.CW2(R5) ;No Extended IRG? BNE RTYCMD ;IF NE, Yes. BR BACK ;Recover from Write Error. ;+ ; -- Read FWD/REV Retry -- ;- REDRTY: REVRTY: CMP MTFC(R2),#NOISE ;800BPI - Min Record? BLO RTYCMD ;IF LO, No - Ignore it. BACK: MOV #FRTRY,R1 ;R1 - Retry Index. MOV IOFCN(R3),R0 ;R0 > ADD #4,R0 ; Reposition Return. MOV (R0)+,DONTBL(R1) ;I/O Cont after Reposition. MOV (R0),U.BUF(R5) ;Setup I/O Request Code. 15$: MOV #-1,U.CNT(R5) ;Reposition by one Block. BR 20$ ;+ ; Reissue Original I/O Request ;- RTYCMD: MOV FCCDE(R3),U.FCDE(R5) ;Restore Function Index, MOV CMDCNT(R3),U.CNT(R5) ; Command Count, MOV BUFADR(R3),U.BUF(R5) ; Buffer Address - 20$: JMP FNCEX ; and Execute the Function. .DSABL LSB .PAGE ;+ ; **-REDDON - Read Forward Completion Routine ;- REVDON: BIC #M.EOF!M.AEOV,U.CW2(R5) ;Setup Status for REV completion. REDDON: MOV MTFC(R2),R1 ;Set Frame Count for Requestor. ; TM03 Formatter - Auto Density setup on Reads. ; IF TM03, Update Density Status for that Tape Unit. TM03DN: BIT #40,MTDT(R2) ;TM03? BEQ 5$ ;IF EQ, No. BIT #M.BOT!M.RWD,U.CW2(R5) ;BOT or Rewinding? BNE 5$ ;IF NE, Yes. BIC #M.1600,U.CW2(R5) ;Assume 800BPI. BIT #PES,MTDS(R2) ;800 BPI? BEQ 5$ ;IF EQ, Yes. BIS #M.1600,U.CW2(R5) ;Else 1600BPI. 5$: TSTB R0 ;Returning Error? BMI EXIT ;IF MI, Yes - More important. BIT #BOT,MTDS(R2) ;Read REV into BOT? BNE EXIT ;IF NE, Yes. CMP MTFC(R2),#NOISE ;Record at least Min Size? BHIS 10$ ;IF HIS, Yes. BIT #M.1600,U.CW2(R5) ;1600 BPI Tape? BNE EXIT ;IF NE, Yes -LT Min allowed for 1600BPI JMP COMRTY ;LT Min not allowed for 800BPI. 10$: CMP R1,U.CNT(R5) ;Tape Data - More than Requested? BLOS EXIT ;IF LOS, No - Success. MOV #IE.DAO&377,R0 ;Inform the User. BR EXIT ;End Request. ;+ ; **-EOFDON - Write Tape Mark Completion Routine ; **-WRTDON - Write Logical Block Completion Routine ;- EOFDON: BIS #M.EOF,U.CW2(R5) ;TMK status. WRTDON: MOV U.CNT(R5),R1 ;Retrieve Requested Count. ADD MTFC(R2),R1 ;Calculate Actual Length. BIT #EOT,MTDS(R2) ;EOT? BEQ EXIT ;IF EQ, No. MOV #IE.EOT&377,R0 ;EOT - Request End Status. BIS #M.EOT,U.CW2(R5) ;EOT in Tape Characteristics Word. BR EXIT ;End Request. RWDDON: BIT #PIP,MTDS(R2) ;Rewind in progress? BEQ 10$ ;IF EQ, Done. BIS #M.RWD,U.CW2(R5) ;Indicate Rewind in Progress. 10$: BIC #M.AEOV,U.CW2(R5) ;No End of Volume indication. BICB #US.PWF,U.STS(R5) ;Clear PWRFLD Status. EXTNST: CLR R1 ;No additional Status being Returned. EXIT: MOV @S.KRB(R4),R2 ;R2 = CSR. CALL MMDINT ;Pass Dev Regs IF User Mode Diag. CALL RLSDRV ;Release the Drive. MOV U.KRB1(R5),R3 ;Retrieve KRB1 Address. MOVB K1.CON(R3),R3 ;Get Formatter Number. ASL R3 ;Make a Word Index. MOVB RTTBL(R3),R2 ;Set Retry Count. BIS #RETRY*256.,R2 ;Set Original Count. BIC #M.PEOV!7,U.CW2(R5) ;No PEOV Status. BICB #US.ABO,U.STS(R5) ;Clear Abort Status. BICB #S3.SIP,S.ST3(R4) ;Clear Status Bit. CALL $RLSUB ;Release the Subcontroller. CALL $RLCN ;Release Controller. BIC #S2.ACT,S.ST2(R4) ;Clear Intrpts active - If Timeout. CLR S.FRK+2(R4) ;Clear the Fork Interlock. CALL $IODON ;End the Request. JMP MMINI ;Service outstanding I/O Requests. ;+ ; **-CHKEOV - Check For Logical End Of Volume ; ; Outputs: ; C=1 If EOV ; C=0 If Not EOV ;- CHKEOV: CLC ;Assume Not EOV. BIT #REV,U.BUF(R5) ;REV Operation? BNE 20$ ;IF NE, Yes - can't be EOV. MOV MTFC(R2),-(SP) ;Retrieve frame Count. SUB U.CNT(R5),(SP) ;Obtain number actually Spaced. CMP (SP)+,#1 ;Exactly One? CLC ;Assume Not EOV. BNE 10$ ;IF NE, No - not EOV. BITB #US.LAB,U.STS(R5) ;Labelled Tape? BNE 10$ ;IF NE, Yes - No EOV. BIT #M.PEOV,U.CW2(R5) ;TMK or BOT seen last time? BEQ 10$ ;IF EQ, No - CC. SEC ;EOV. 10$: BIS #M.EOF,U.CW2(R5) ;Set EOF status 20$: RETURN .PAGE ;+ ; **-SELDRV - Select Tape Unit ; **-SELECT - Select And Set Hardware Status ; ; This routine attempts to select a drive. ; It sets up BOT, EOT, HWL, SER bits in the Tape Characteristics Word. ; ; Outputs: ; C=0 If Good Select ; C=1 If Bad Select ;- SELDRV: MOV @S.KRB(R4),R2 ;R2 - CSR. MOVB U.UNIT(R5),RHCS2(R2) ;Select the formatter. BIT #GO,(R2) ;Go Bit Set? BNE 10$ ;IF NE, Yes - don't touch MTTC ! MOV MTTC(R2),-(SP) ;Save Slave Select Register. MOVB U.SNUM(R5),(SP) ;Select MOV (SP)+,MTTC(R2) ; Slave Unit. 10$: RETURN SELECT: CALL SELDRV ;Select Formatter and Slave. BIC #M.BOT!M.EOT!M.HWL!M.SER,U.CW2(R5) ;Status to be updated. SEC ;Assume can't select Tape Drive. BIT #MOL,MTDS(R2) ;Tape Drive Ready? BNE 10$ ;IF NE, Yes. BIS #M.SER,U.CW2(R5) ;Select Error - indicate it. RETURN 10$: BIT #PIP,MTDS(R2) ;Positioning in Progress? BNE 20$ ;IF NE, Yes. BIT #BOT,MTDS(R2) ;Tape at BOT? BEQ 15$ ;IF EQ, No. BIS #M.BOT,U.CW2(R5) ;BOT status, BIC #M.RWD,U.CW2(R5) ; not Rewinding. 15$: BIT #EOT,MTDS(R2) ;Tape at EOT? BEQ 20$ ;IF EQ, No. BIS #M.EOT,U.CW2(R5) ;EOT status. 20$: BIT #WRL,MTDS(R2) ;Tape Drive Write-Locked? BEQ 30$ ;IF EQ, No. BIS #M.HWL,U.CW2(R5) ;HWL status. 30$: CLC ;Tape Drive available. RTRN: RETURN ;+ ; **-LOGERR - Subroutine To Log Device Errors ;- LOGERR: TST RTTBL(R3) ;User Mode Function? BMI RTRN ;IF MI, Yes - They will handle it. JMP $DVERR ;Log the Error - They will RTRN. .PAGE ;+ ; **-$RQSUB-Request Subcontroller ; ; Obtain Access To Subcontroller - ; IF Allowed to perform an I/O Operation, Set Subcontroller Busy. ; ; Inputs: ; R5 > UCB, Requestor Unit. 0(SP)= > Driver Return ; 2(SP)= > Drivers Caller ; Outputs: ; R4 > SCB, ; R5 > UCB, Requestor Unit. ; ; NOTE: ; S.FRK+2 is Always Non-Zero. ; Driver has Exclusive Access to Subcontroller. ;- $RQSUB: MOV U.SCB(R5),R1 ;R1 > SCB. MOV U.KRB1(R5),R0 ;R0 > KRB1. CMP R5,K1.OWN(R0) ;Requestor already own Subcontroller? BEQ 10$ ;IF EQ, Yes. TST K1.OWN(R0) ;Subcontroller Busy? BNE 20$ ;IF NE, Yes. MOV R5,K1.OWN(R0) ;Requestor - Subcontroller Owner. ; Requestor Subcontroller Owner. 10$: MOV R1,R4 ;Subcontroller Owner - MOV #42,S.FRK+2(R4) ; IF S.FRK+2 .NE. - owned. RETURN ; Requestor not Subcontroller Owner .and. Subcontroller Busy. 20$: MOV R1,S.FRK+6(R1) ; Save SCB in R4 Save Area. ADD #S.FRK+6,R1 ; R1 > to R5 Save Area+2; MOV R5,-(R1) ; Save R5, MOV (SP)+,-(R1) ; Save Drivers Return @, CLR -(R1) ; and Clear Link Word. ADD #K1.CRQ,R0 ; R0 > to Wait Queue JMP $QINSF ; and Queue this Request. ;+ ; **-$RLSUB-Release Subcontroller ; ; IF Requestor not Subcontroller Owner, Return. ; ; ELSE Release Subcontroller, place Fork Block for subsequent ; Requests (if any) from the Controller Wait Queue to the ; Fork Queue and make Requestor the Owner of the Subcontroller. ; ; Inputs: ; R4 > SCB, ; R5 > UCB of Requestor. ; ; Outputs: ; IF Owned - Subcontroller Released ; R3 Altered ;- $RLSUB: MOV U.KRB1(R5),R3 ;R3 > KRB1. CMP R5,K1.OWN(R3) ;Requestor own Subcontroller? BNE 30$ ;IF NE, No. ; Requestor owns Subcontroller. CLR K1.OWN(R3) ;Release Subcontroller ownership. ; Handle other Requestors Queued. ADD #K1.CRQ,R3 ;R3 > Subcontroller Request Queue. MOV (R3),R4 ;Any other Requestors Queued? BEQ 20$ ;IF EQ, No other Requestors Queued. MOV (R4),(R3) ;Update Beginning of List. BNE 10$ ;IF NE, List updated. MOV R3,2(R3) ;Empty list. 10$: MOV 4(R4),K1.OWN-K1.CRQ(R3) ;Prev Reqstr - R5 from Fork List. CLR (R4) ;Clear Fork Link Word. CALL $QFORK ;Fork Block to Fork Queue. 20$: MOV U.SCB(R5),R4 ;R4 > SCB. 30$: RETURN ;+ ; **-RLSDRV - Release the Drive ; ; IF A Multi Access (Dual Ported) Unit, Issue Drive Release and note in SCB. ; ; Inputs: ; R2 > CSR. ; R4 > SCB. ;- RLSDRV: MOVB #TRE/256.,1(R2) ;Clear RH errors - CS1 14,13; CS2 15-8. BIT #PIP,MTDS(R2) ;Tape movement? BNE 5$ ;IF NE, Yes - Can't init RH, tape subsy MOV #TRE!10,(R2) ;Clear RH errors, selected TM. 5$: BIT #S2.MAD,S.ST2(R4) ;RH01? BEQ 10$ ;IF EQ, No. MOVB #FC.RLS,(R2) ;Release Drive (Subcontroler). BISB #S3.DRL,S.ST3(R4) ; and Show Dual Access Unit released. 10$: MOVB #IE,(R2) ;Re-enable Interrupts. RETURN .PAGE ;+ ; **-MMDINT ; ; IF Diagnostic Control Function, ; pass Device Registers via $CRPAS routine. ; ; Inputs: ; R2 > CSR R4 > SCB ;- MMDINT: MOV R1,-(SP) ;Save R1 MOV S.PKT(R4),R1 ;Get I/O Packet Address BITB #IQ.UMD,I.FCN(R1) ;Diagnostic Function Call? BEQ 20$ ;IF EQ, No. CMPB #IO.EOF/256.,I.FCN+1(R1) ;Write EOF Control Function? BEQ 10$ ;IF EQ, Yes. CMPB #IO.RWD/256.,I.FCN+1(R1) ;Control other than IO.EOF? BEQ 10$ ;IF EQ, Yes. CALL $CRPAS ;Pass Device Registers to Diagnostics BR 20$ ; .. Cont. 10$: MOV I.PRM+14(R1),I.PRM+16(R1) ;Move WD20 to WD21 MOV I.PRM+12(R1),I.PRM+14(R1) ;Move WD17 to WD20 MOV R1,-(SP) ;Save I/O Packet Address CALL $CRPAS ;Pass Device Registers to Diagnostics MOV (SP)+,R1 ;Restore I/O Packet Address MOV I.PRM+14(R1),I.PRM+12(R1) ;Move WD20 back to WD17 MOV I.PRM+16(R1),I.PRM+14(R1) ;Move WD21 back to WD20 20$: MOV (SP)+,R1 ;Restore R1 RETURN .END